package com.org.api.admin.service.impl;

import com.alibaba.fastjson.JSON;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.org.api.admin.entity.po.*;
import com.org.api.admin.service.*;
import com.org.platform.model.ResultModel;
import com.org.platform.utils.CommonUtil;
import com.org.platform.utils.LocalDateUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * @Description
 * @auther dh
 * @date 2022/3/1 15:53
 */
@Slf4j
@Service
public class CmsUserRedisServiceImpl implements CmsUserRedisService {

    public static final long maxEndTimestamp = 9999999999999L;

    public static final String redisIndexId = "indexId";

    public static final String oneString = "1";

    public static final String modulePrefix = "cms:ind_mod:";

    public static final String moduleDetailPrefix = "cms:ind_mod_detail:";

    public static final String moduleDetailUserPrefix = "cms:ind_mod_detail:user:";

//    public static final String moduleDetailBannerPrefix = "cms:ind_mod_detail:banner:";
//
//    public static final String moduleDetailBannerUserPrefix = "cms:ind_mod_detail:banner:user:";

    public static final String moduleUserAreaPrefix = "ua:";

    public static final String moduleUserTypePrefix = "ut:";

    public static final ObjectMapper objectMapper = new ObjectMapper();

    public static ObjectMapper getObjectMapper() {
        return objectMapper;
    }

    @Autowired
    private RedisTemplate redisTemplate;

  /*  @Autowired
    private CmsUserMobileNavigationService cmsUserMobileNavigationService;

    @Autowired
    private CmsUserMobileBannerService cmsUserMobileBannerService;

    @Autowired
    private CmsUserMobileGraphicNavigationService cmsUserMobileGraphicNavigationService;
*/
    /**
     * 用于判断是否默认或者长期
     */
    @Override
    public boolean isLongTeamOrDefault(CmsUserRedisIndex cmsUserRedisIndex) {
        if (null != cmsUserRedisIndex && (cmsUserRedisIndex.getIsLongTeam().equals(1) || cmsUserRedisIndex.getIsDefault().equals(1))) {
            return true;
        }
        return false;
    }

    /**
     * 用于计算score
     */
    private long getEndTimestamp(CmsUserRedisIndex cmsUserRedisIndex) {
        long endTimestamp = maxEndTimestamp;
        if (!isLongTeamOrDefault(cmsUserRedisIndex)) {
            String endTimeString = cmsUserRedisIndex.getShowEndTime();
            LocalDateTime endDateTime = LocalDateUtil.localDateTimeParse(endTimeString, LocalDateUtil.FORMAT_PATTERN1);
            Date endDate = LocalDateUtil.localDateTimeToDate(endDateTime);
            endTimestamp = endDate.getTime();
        }
        return endTimestamp;
    }

    @Override
    public long getExpireTimeByEndTime(String showEndTime) {
        long expireTime;
        LocalDateTime endDateTime = LocalDateUtil.localDateTimeParse(showEndTime, LocalDateUtil.FORMAT_PATTERN1);
        LocalDateTime nowTime = LocalDateTime.now();
        if (endDateTime.compareTo(nowTime) > 0) {
            expireTime = LocalDateUtil.minusToMillsLocalDateTime(nowTime, endDateTime);
            expireTime = expireTime + (10 * 1000);
        } else {
            expireTime = 1 * 1000; // 默认一秒过期
        }
        return expireTime;
    }

    @Override
    public long getModuleExpireTime(CmsUserRedisIndex cmsUserRedisIndex) {
        long expireTime = -1; // key过期时间,精确到毫秒
        if (!isLongTeamOrDefault(cmsUserRedisIndex)) {
            expireTime = getExpireTimeByEndTime(cmsUserRedisIndex.getShowEndTime());
        }
        return expireTime;
    }

    @Override
    public long getModuleDetailExpireTime(Integer isLongTerm, String showEndTime) {
        long expireTime = -1;
        if (isLongTerm.equals(0)) {
            expireTime = getExpireTimeByEndTime(showEndTime);
        }
        return expireTime;
    }

    /**
     * 保存首页数据
     */
    @Override
    public ResultModel saveIndexData(String keyPrefix, String[] keys, CmsUserRedisIndex cmsUserRedisIndex) {

//  计算结束时间戳
        Double score = Double.valueOf(getEndTimestamp(cmsUserRedisIndex));
//	当前时间戳
        Date now = new Date();
        long nowTimestamp = now.getTime();
        Double expireScore = Double.valueOf(nowTimestamp);
//	一个key一个key的计算
        for (String key : keys) {
            String theKey = key;
            String isInUse = oneString; // 判断是否有用,可能是删除的
            String[] keyArray = key.split("\\:");
            if (null != keyArray && keyArray.length == 2) {
                theKey = keyArray[0];
                isInUse = keyArray[1];
            }
            String redisKey = keyPrefix + theKey;
            // 1、先删除过期的数据,结束时间在当前时间之前的数据全部删掉
            redisTemplate.opsForZSet().removeRangeByScore(redisKey, 0, expireScore);
            // 2、删除已有需要保存的数据,查找结束时间之间的数据
            deleteCmsIndex(redisKey, cmsUserRedisIndex, score, isInUse);
            // 3、保存数据
            addCmsRedisIndex(redisKey, cmsUserRedisIndex, score, isInUse);
        }
        return ResultModel.newSuccess();
    }


    public void deleteCmsIndex(String redisKey, CmsUserRedisIndex cmsUserRedisIndex, Double score, String isInUse) {
        Set<CmsUserRedisIndex> cmsIndexSet = redisTemplate.opsForZSet().rangeByScore(redisKey, 0, maxEndTimestamp);
        if (null == cmsIndexSet || cmsIndexSet.size() <= 0) {
            return;
        }
        for (CmsUserRedisIndex redisIndex : cmsIndexSet) {
            Long indId = redisIndex.getIndexId();
            if (null == indId || !indId.equals(cmsUserRedisIndex.getIndexId())) {
                continue;
            }
            redisTemplate.opsForZSet().remove(redisKey, redisIndex);
            addCmsRedisIndex(redisKey, cmsUserRedisIndex, score, isInUse);
        }
    }

    public void addCmsRedisIndex(String redisKey, CmsUserRedisIndex cmsUserRedisIndex, Double score, String isInUse) {
        if (null == cmsUserRedisIndex) {
            return;
        }
        Integer configStatus = cmsUserRedisIndex.getConfigStatus(); // 1=启用,0=禁用
        Integer isDelete = cmsUserRedisIndex.getIsDelete(); // 1=删除,0=未删除
        if (null == configStatus || !configStatus.equals(1)
                || null == isDelete || !isDelete.equals(0)
                || null == isInUse || !isInUse.equals(oneString)) {
            log.info("cms活动:{}状态不正确", JSON.toJSONString(cmsUserRedisIndex));
            return;
        }
        if (!isLongTeamOrDefault(cmsUserRedisIndex)) {
            LocalDateTime endDateTime = LocalDateUtil.localDateTimeParse(cmsUserRedisIndex.getShowEndTime(), LocalDateUtil.FORMAT_PATTERN1);
            LocalDateTime nowTime = LocalDateTime.now();
            if (endDateTime.compareTo(nowTime) <= 0) {
                log.info("cms活动:{}过期了", JSON.toJSONString(cmsUserRedisIndex));
                return; // 这里过期了
            }
        }
        redisTemplate.opsForZSet().add(redisKey, cmsUserRedisIndex, score);
    }

    /**
     * 保存模块数据
     */
    @Override
    public ResultModel saveIndexModuleData(String keyPrefix, List<CmsUserRedisIndexModule> cmsUserRedisIndexModuleList, CmsUserRedisIndex cmsUserRedisIndex) {
        if (null == cmsUserRedisIndexModuleList || cmsUserRedisIndexModuleList.size() <= 0) {
            return ResultModel.newSuccess();
        }
        long expireTime = getModuleExpireTime(cmsUserRedisIndex);
        // 先查询数据
        for (CmsUserRedisIndexModule cmsUserRedisIndexModule : cmsUserRedisIndexModuleList) {
            initModuleData(cmsUserRedisIndexModule);
        }
        // 填充数据到redis
        for (CmsUserRedisIndexModule cmsUserRedisIndexModule : cmsUserRedisIndexModuleList) {
            invokeModuleData(cmsUserRedisIndexModule);
        }
        Integer configStatus = cmsUserRedisIndex.getConfigStatus();
        Integer isDelete = cmsUserRedisIndex.getIsDelete();
        String moduleKeyPrefix = keyPrefix + cmsUserRedisIndex.getIndexId();
        redisTemplate.delete(moduleKeyPrefix);
        if (null == configStatus || !configStatus.equals(1) || null == isDelete || !isDelete.equals(0)) {
            log.info("该数据已禁用或已删除");
            return ResultModel.newSuccess();
        }
        // 这里只查询未删除的模块数据
        List<CmsUserRedisIndexModule> dataList = cmsUserRedisIndexModuleList.stream().filter(e -> e.getIsDelete().equals(0)).collect(Collectors.toList());
        redisTemplate.opsForList().leftPushAll(moduleKeyPrefix, dataList);
        if (expireTime > 0) {
            redisTemplate.expire(moduleKeyPrefix, expireTime, TimeUnit.MILLISECONDS);
        }
        return ResultModel.newSuccess();
    }

    public ResultModel initModuleData(CmsUserRedisIndexModule cmsUserRedisIndexModule) {
        CmsUserBaseService cmsUserBaseService = cmsUserRedisIndexModule.getCmsUserBaseService();
        cmsUserRedisIndexModule.setModuleDetailData(cmsUserBaseService.getModuleDetailData(cmsUserRedisIndexModule));
        /*
        String moduleType = cmsUserRedisIndexModule.getModuleType();
        if (null != moduleType && moduleType.equals(CmsUserModuleEnum.Navigation.getModuleType())) {
            // 导航
            List<CmsUserMobileNavigationDetailVO> moduleDetailData = cmsUserMobileNavigationService.getModuleDetailData(cmsUserRedisIndexModule);
            cmsUserRedisIndexModule.setModuleDetailData(moduleDetailData);
        }
        if (null != moduleType && moduleType.equals(CmsUserModuleEnum.Banner.getModuleType())) {
            // banner
            List<CmsUserMobileBannerVO> moduleDetailData = cmsUserMobileBannerService.getModuleDetailData(cmsUserRedisIndexModule);
            cmsUserRedisIndexModule.setModuleDetailData(moduleDetailData);
        }
        if (null != moduleType && moduleType.equals(CmsUserModuleEnum.GraphicNavigation.getModuleType())) {
            // 图文导航
            CmsUserMobileGraphicNavigationVO  moduleDetailData = cmsUserMobileGraphicNavigationService.getModuleDetailData(cmsUserRedisIndexModule);
            cmsUserRedisIndexModule.setModuleDetailData(moduleDetailData);
        }*/
        return ResultModel.newSuccess();
    }

    public ResultModel invokeModuleData(CmsUserRedisIndexModule cmsUserRedisIndexModule) {
	      CmsUserBaseService cmsUserBaseService = cmsUserRedisIndexModule.getCmsUserBaseService();
	      cmsUserBaseService.invokeModuleDetailData(cmsUserRedisIndexModule);
        /*String moduleType = cmsUserRedisIndexModule.getModuleType();
        if (null != moduleType && moduleType.equals(CmsUserModuleEnum.Navigation.getModuleType())) {
            // 导航
            cmsUserMobileNavigationService.invokeModuleDetailData(cmsUserRedisIndexModule);
        }
        if (null != moduleType && moduleType.equals(CmsUserModuleEnum.Banner.getModuleType())) {
            // banner
            cmsUserMobileBannerService.invokeModuleDetailData(cmsUserRedisIndexModule);
        }
        if (null != moduleType && moduleType.equals(CmsUserModuleEnum.GraphicNavigation.getModuleType())) {
            // 图文导航
            cmsUserMobileGraphicNavigationService.invokeModuleDetailData(cmsUserRedisIndexModule);
        }*/
        return ResultModel.newSuccess();
    }

    /**
     * 获取首页详情数据
     */
    @Override
    public List<Object> getIndexModuleData(List<Object> moduleList) {
        List<Object> resultModuleList = new ArrayList<>();
        if (null == moduleList || moduleList.size() <= 0) {
            return resultModuleList;
        }
        for (Object module : moduleList) {
            CmsUserRedisIndexModule cmsUserRedisIndexModule = CmsUserRedisServiceImpl.getObjectMapper().convertValue(module, CmsUserRedisIndexModule.class);
            cmsUserRedisIndexModule.fillServiceClass();
	          CmsUserBaseService cmsUserBaseService = cmsUserRedisIndexModule.getCmsUserBaseService();
	          CmsUserBaseResultVO moduleData  = (CmsUserBaseResultVO)cmsUserBaseService.getRedisDataList(cmsUserRedisIndexModule);
            /*String moduleType = cmsUserRedisIndexModule.getModuleType();
            CmsUserBaseResultVO moduleData = null;
            if (null != moduleType && moduleType.equals(CmsUserModuleEnum.Navigation.getModuleType())) {
                // 导航
                moduleData = cmsUserMobileNavigationService.getRedisDataList(cmsUserRedisIndexModule);
            }
            if (null != moduleType && moduleType.equals(CmsUserModuleEnum.Banner.getModuleType())) {
                // banner
                moduleData = cmsUserMobileBannerService.getRedisDataList(cmsUserRedisIndexModule);
            }
            if (null != moduleType && moduleType.equals(CmsUserModuleEnum.GraphicNavigation.getModuleType())) {
                // 图文导航
                moduleData = cmsUserMobileGraphicNavigationService.getRedisDataList(cmsUserRedisIndexModule);
            }*/
            if (null == moduleData || null == moduleData.getList() || moduleData.getList().size() <= 0) {
                continue;
            }
            resultModuleList.add(moduleData);
        }
        return resultModuleList;
    }
}
